/*******************************************************************************
 * Copyright (c) 2013 University of Luxembourg and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     @author Qin ZHANG ("Jackin" as a Global Communication ID)
 ******************************************************************************/

package lu.uni.geko.ext.ram;

import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.util.EcoreUtil.Copier;

/**
 * @author Jackin
 * 
 * This is an extended EcoreUtil.Copier for copying base to woven model,
 * while removing the instantiation.
 */
public class EcoreUtilCopierExt extends Copier {
	
	private static final long serialVersionUID = 1L;

	/**
	 * Returns a self-contained copy of the eObject without the "Instantiation" feature.
	 * @param eObject the object to copy.
	 * @return the copy.
	 */
	public <T extends EObject> T extCopy(T eObject)
	{
		EObject result = copy(eObject);
		copyReferences();

		@SuppressWarnings("unchecked")T t = (T)result;
		return t;
	}

	@Override
	public EObject copy(EObject eObject)
	{
		if (eObject == null)
		{
			return null;
		}
		else
		{
			EObject copyEObject = createCopy(eObject);
			put(eObject, copyEObject);
			EClass eClass = eObject.eClass();
			for (int i = 0, size = eClass.getFeatureCount(); i < size; ++i)
			{
				EStructuralFeature eStructuralFeature = eClass.getEStructuralFeature(i);

				// extension: do not copy "instantiations"
				if (eStructuralFeature.getName().equalsIgnoreCase(RamConstants.instantiations)) continue;

				if (eStructuralFeature.isChangeable() && !eStructuralFeature.isDerived())
				{
					if (eStructuralFeature instanceof EAttribute)
					{
						copyAttribute((EAttribute)eStructuralFeature, eObject, copyEObject);
					}
					else
					{
						EReference eReference = (EReference)eStructuralFeature;
						if (eReference.isContainment())
						{
							copyContainment(eReference, eObject, copyEObject);
						}
					}
				}
			}

			copyProxyURI(eObject, copyEObject);

			return copyEObject;
		}
	}
}
